# -*- mode: perl; -*-

use strict;
use warnings;

use Test::More tests => 858;

my $class;

BEGIN {
    $class = 'Math::BigInt';
    use_ok($class);
}

can_ok($class, 'backermann', 'ackermann');

while (<DATA>) {
    s/#.*$//;                   # remove comments
    s/\s+$//;                   # remove trailing whitespace
    next unless length;         # skip empty lines

    my ($m, $n, $expected) = split /:/;

    # backermann() modifies the invocand.

    {
        my ($x, $y);
        my $test = qq|\$x = $class->new("$m"); \$y = \$x->backermann("$n");|;

        subtest $test,
          sub {
              plan tests => 4;

              eval $test;
              is($@, "", "'$test' gives emtpy \$\@");

              is(ref($y), $class,
                 "'$test' output arg is a $class");

              is($y -> bstr(), $expected,
                 "'$test' output arg has the right value");

              is($x -> bstr(), $expected,
                 "'$test' invocand has the right value");
          };
    }

    # ackermann() does not modify the invocand.

    {
        my ($x, $y);
        my $test = qq|\$x = $class->new("$m"); \$y = \$x->ackermann("$n");|;

        subtest $test,
          sub {
              plan tests => 4;

              eval $test;
              is($@, "", "'$test' gives emtpy \$\@");

              is(ref($y), $class,
                 "'$test' output arg is a $class");

              is($y -> bstr(), $expected,
                 "'$test' output arg has the right value");

              is($x -> bstr(), $m,
                 "'$test' invocand has the right value");
          };
    }
}

__DATA__

0:0:1
0:1:2
0:2:3
0:3:4
0:4:5
0:5:6
0:6:7
0:7:8
0:8:9
0:9:10
0:10:11
0:11:12
0:12:13
0:13:14
0:14:15
0:15:16
0:16:17
0:17:18
0:18:19
0:19:20
0:20:21
0:21:22
0:22:23
0:23:24
0:24:25
0:25:26
0:26:27
0:27:28
0:28:29
0:29:30
0:30:31
0:31:32
0:32:33
0:33:34
0:34:35
0:35:36
0:36:37
0:37:38
0:38:39
0:39:40
0:40:41
0:41:42
0:42:43
0:43:44
0:44:45
0:45:46
0:46:47
0:47:48
0:48:49
0:49:50
0:50:51
0:51:52
0:52:53
0:53:54
0:54:55
0:55:56
0:56:57
0:57:58
0:58:59
0:59:60
0:60:61
0:61:62
0:62:63
0:63:64
0:64:65
0:65:66
0:66:67
0:67:68
0:68:69
0:69:70
0:70:71
0:71:72
0:72:73
0:73:74
0:74:75
0:75:76
0:76:77
0:77:78
0:78:79
0:79:80
0:80:81
0:81:82
0:82:83
0:83:84
0:84:85
0:85:86
0:86:87
0:87:88
0:88:89
0:89:90
0:90:91
0:91:92
0:92:93
0:93:94
0:94:95
0:95:96
0:96:97
0:97:98
0:98:99
0:99:100
0:100:101
0:1000:1001
0:100000:100001
0:10000000:10000001
0:10000000000:10000000001
0:10000000000000:10000000000001
0:10000000000000000000000000000000000:10000000000000000000000000000000001
0:12345678987654321012345678987654321:12345678987654321012345678987654322

1:0:2
1:1:3
1:2:4
1:3:5
1:4:6
1:5:7
1:6:8
1:7:9
1:8:10
1:9:11
1:10:12
1:11:13
1:12:14
1:13:15
1:14:16
1:15:17
1:16:18
1:17:19
1:18:20
1:19:21
1:20:22
1:21:23
1:22:24
1:23:25
1:24:26
1:25:27
1:26:28
1:27:29
1:28:30
1:29:31
1:30:32
1:31:33
1:32:34
1:33:35
1:34:36
1:35:37
1:36:38
1:37:39
1:38:40
1:39:41
1:40:42
1:41:43
1:42:44
1:43:45
1:44:46
1:45:47
1:46:48
1:47:49
1:48:50
1:49:51
1:50:52
1:51:53
1:52:54
1:53:55
1:54:56
1:55:57
1:56:58
1:57:59
1:58:60
1:59:61
1:60:62
1:61:63
1:62:64
1:63:65
1:64:66
1:65:67
1:66:68
1:67:69
1:68:70
1:69:71
1:70:72
1:71:73
1:72:74
1:73:75
1:74:76
1:75:77
1:76:78
1:77:79
1:78:80
1:79:81
1:80:82
1:81:83
1:82:84
1:83:85
1:84:86
1:85:87
1:86:88
1:87:89
1:88:90
1:89:91
1:90:92
1:91:93
1:92:94
1:93:95
1:94:96
1:95:97
1:96:98
1:97:99
1:98:100
1:99:101
1:100:102
1:1000:1002
1:100000:100002
1:10000000:10000002
1:10000000000:10000000002
1:10000000000000:10000000000002
1:10000000000000000000000000000000000:10000000000000000000000000000000002
1:12345678987654321012345678987654321:12345678987654321012345678987654323

2:0:3
2:1:5
2:2:7
2:3:9
2:4:11
2:5:13
2:6:15
2:7:17
2:8:19
2:9:21
2:10:23
2:11:25
2:12:27
2:13:29
2:14:31
2:15:33
2:16:35
2:17:37
2:18:39
2:19:41
2:20:43
2:21:45
2:22:47
2:23:49
2:24:51
2:25:53
2:26:55
2:27:57
2:28:59
2:29:61
2:30:63
2:31:65
2:32:67
2:33:69
2:34:71
2:35:73
2:36:75
2:37:77
2:38:79
2:39:81
2:40:83
2:41:85
2:42:87
2:43:89
2:44:91
2:45:93
2:46:95
2:47:97
2:48:99
2:49:101
2:50:103
2:51:105
2:52:107
2:53:109
2:54:111
2:55:113
2:56:115
2:57:117
2:58:119
2:59:121
2:60:123
2:61:125
2:62:127
2:63:129
2:64:131
2:65:133
2:66:135
2:67:137
2:68:139
2:69:141
2:70:143
2:71:145
2:72:147
2:73:149
2:74:151
2:75:153
2:76:155
2:77:157
2:78:159
2:79:161
2:80:163
2:81:165
2:82:167
2:83:169
2:84:171
2:85:173
2:86:175
2:87:177
2:88:179
2:89:181
2:90:183
2:91:185
2:92:187
2:93:189
2:94:191
2:95:193
2:96:195
2:97:197
2:98:199
2:99:201
2:100:203
2:1000:2003
2:100000:200003
2:10000000:20000003
2:10000000000:20000000003
2:10000000000000:20000000000003
2:10000000000000000000000000000000000:20000000000000000000000000000000003
2:12345678987654321012345678987654321:24691357975308642024691357975308645

3:0:5
3:1:13
3:2:29
3:3:61
3:4:125
3:5:253
3:6:509
3:7:1021
3:8:2045
3:9:4093
3:10:8189
3:11:16381
3:12:32765
3:13:65533
3:14:131069
3:15:262141
3:16:524285
3:17:1048573
3:18:2097149
3:19:4194301
3:20:8388605
3:21:16777213
3:22:33554429
3:23:67108861
3:24:134217725
3:25:268435453
3:26:536870909
3:27:1073741821
3:28:2147483645
3:29:4294967293
3:30:8589934589
3:31:17179869181
3:32:34359738365
3:33:68719476733
3:34:137438953469
3:35:274877906941
3:36:549755813885
3:37:1099511627773
3:38:2199023255549
3:39:4398046511101
3:40:8796093022205
3:41:17592186044413
3:42:35184372088829
3:43:70368744177661
3:44:140737488355325
3:45:281474976710653
3:46:562949953421309
3:47:1125899906842621
3:48:2251799813685245
3:49:4503599627370493
3:50:9007199254740989
3:51:18014398509481981
3:52:36028797018963965
3:53:72057594037927933
3:54:144115188075855869
3:55:288230376151711741
3:56:576460752303423485
3:57:1152921504606846973
3:58:2305843009213693949
3:59:4611686018427387901
3:60:9223372036854775805
3:61:18446744073709551613
3:62:36893488147419103229
3:63:73786976294838206461
3:64:147573952589676412925
3:65:295147905179352825853
3:66:590295810358705651709
3:67:1180591620717411303421
3:68:2361183241434822606845
3:69:4722366482869645213693
3:70:9444732965739290427389
3:71:18889465931478580854781
3:72:37778931862957161709565
3:73:75557863725914323419133
3:74:151115727451828646838269
3:75:302231454903657293676541
3:76:604462909807314587353085
3:77:1208925819614629174706173
3:78:2417851639229258349412349
3:79:4835703278458516698824701
3:80:9671406556917033397649405
3:81:19342813113834066795298813
3:82:38685626227668133590597629
3:83:77371252455336267181195261
3:84:154742504910672534362390525
3:85:309485009821345068724781053
3:86:618970019642690137449562109
3:87:1237940039285380274899124221
3:88:2475880078570760549798248445
3:89:4951760157141521099596496893
3:90:9903520314283042199192993789
3:91:19807040628566084398385987581
3:92:39614081257132168796771975165
3:93:79228162514264337593543950333
3:94:158456325028528675187087900669
3:95:316912650057057350374175801341
3:96:633825300114114700748351602685
3:97:1267650600228229401496703205373
3:98:2535301200456458802993406410749
3:99:5070602400912917605986812821501
3:100:10141204801825835211973625643005

4:0:13
4:1:65533

5:0:65533
